import pygame
import pyaudio
import wave
import datetime
import numpy as np
import random
import matplotlib.pyplot as plt

# 音频输入参数
format = pyaudio.paInt16
channels = 1
rate = 44100
chunk_size = 1024
record_seconds = 2
cooldown_time = 1  # HIT 计数的冷却时间，单位为秒

# Pygame窗口尺寸
WIDTH = 800
HEIGHT = 600

# 初始化Pygame
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("剪刀石头布游戏")

# 背景颜色
BACKGROUND_COLOR = (255, 255, 255)

# 音频对象
audio = pyaudio.PyAudio()
stream = audio.open(format=format,
                    channels=channels,
                    rate=rate,
                    input=True,
                    frames_per_buffer=chunk_size)

# 上一次 HIT 的时间
last_hit_time = None

# 上一次录音的文件名
last_filename = None

# 游戏数据
score_player = 0
score_computer = 0

def draw_text(text, font, color, x, y):
    # 绘制文本
    text_surface = font.render(text, True, color)
    text_rect = text_surface.get_rect()
    text_rect.center = (x, y)
    screen.blit(text_surface, text_rect)

def calculate_threshold(audio_data):
    max_amplitude = np.max(audio_data)
    hit_threshold = int(0.5 * max_amplitude)

    print(f"threshold: {hit_threshold}")
    return hit_threshold

def count_hits(audio_data, threshold):
    hit_count = 0
    skip_count = 0

    for i, sample in enumerate(audio_data):
        if skip_count > 0:
            skip_count -= 1
            continue

        if sample > threshold:
            print(f"HIT: {i}: {sample}")
            hit_count += 1
            skip_count = 199 # int(rate / chunk_size * cooldown_time)

    return hit_count

def save_audio(filename, frames):
    with wave.open(filename, "wb") as wf:
        wf.setnchannels(channels)
        wf.setsampwidth(audio.get_sample_size(format))
        wf.setframerate(rate)
        wf.writeframes(b''.join(frames))

def plot_waveform(audio_data):
    # 创建时间轴
    time_axis = np.arange(0, len(audio_data)) / rate

    # 绘制波形图
    plt.figure()
    plt.plot(time_axis, audio_data)
    plt.xlabel("Time (s)")
    plt.ylabel("Amplitude")
    plt.title("Waveform")
    plt.show()

def get_user_choice():
    while True:
        choice = input("请出拳（剪刀/石头/布）：")
        if choice in ['剪刀', '石头', '布']:
            return choice
        else:
            print("输入无效，请重新输入！")

def get_computer_choice():
    choices = ['剪刀', '石头', '布']
    return random.choice(choices)

def determine_winner(user_choice, computer_choice):
    if user_choice == computer_choice:
        return "平局"
    elif (user_choice == '剪刀' and computer_choice == '布') or \
            (user_choice == '石头' and computer_choice == '剪刀') or \
            (user_choice == '布' and computer_choice == '石头'):
        return "用户胜利"
    else:
        return "电脑胜利"

def draw_game_interface():
    screen.fill(BACKGROUND_COLOR)

    # 绘制计数轴和提示信息
    draw_text("按空格键开始录音", pygame.font.Font(None, 30), (0, 0, 0), WIDTH // 2, HEIGHT // 2)
    draw_text("剪刀(1) 石头(2) 布(3)", pygame.font.Font(None, 30), (0, 0, 0), WIDTH // 2, HEIGHT // 2 + 50)

    # 绘制波形图
    if last_filename:
        with wave.open(last_filename, "rb") as wf:
            num_frames = wf.getnframes()
            audio_data = np.frombuffer(wf.readframes(num_frames), dtype=np.int16)
        plot_waveform(audio_data)

    # 绘制胜负次数
    draw_text(f"玩家: {score_player}, 电脑: {score_computer}", pygame.font.Font(None, 30), (0, 0, 0), WIDTH // 2, 50)

    pygame.display.flip()

score_player = 0
score_computer = 0

def game_loop():

    global score_player, score_computer
    
    running = True
    recording = False
    player_input = []

    while running:
        draw_game_interface()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    if not recording:
                        recording = True
                        
                        # 开始录音
                        frames = []
                        for i in range(int(rate / chunk_size * record_seconds)):
                            data = stream.read(chunk_size)
                            frames.append(data)

                        current_time = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
                        filename = f"audio_{current_time}.wav"
                        save_audio(filename, frames)
                        print(f"音频已保存为：{filename}")
                        last_filename = filename

                        with wave.open(filename, "rb") as wf:
                            num_frames = wf.getnframes()
                            audio_data = np.frombuffer(wf.readframes(num_frames), dtype=np.int16)

                        hit_threshold = calculate_threshold(audio_data)
                        hit_count = count_hits(audio_data, hit_threshold)
                        print(f"HIT次数：{hit_count}")

                        if hit_count == 1:
                            user_choice = '剪刀'
                        elif hit_count == 2:
                            user_choice = '石头'
                        elif hit_count == 3:
                            user_choice = '布'
                        else:
                            user_choice = get_user_choice()
                            
                        player_input.append(user_choice)

                        computer_choice = get_computer_choice()
                        print("用户选择:", user_choice)
                        print("电脑选择:", computer_choice)
                        winner = determine_winner(user_choice, computer_choice)
                        print("结果:", winner)

                        draw_game_interface()

                        pygame.time.delay(2000)  # 等待2秒以显示结果

                        if winner == "用户胜利":
                            score_player += 1
                        elif winner == "电脑胜利":
                            score_computer += 1

                        recording = False
                        player_input = []

                        draw_game_interface()

                    else:
                        player_input = []

                        draw_game_interface()

        pygame.display.flip()

    pygame.quit()

# 启动游戏循环

score_player = 0
score_computer = 0
game_loop()
